﻿using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NetAssist.Pooling;
//using System.Collections;

namespace NetAssistTests
{
  [TestClass()]
  public class PoolingTests
  {
    [TestMethod()]
    public void PoolingTest1()
    {
      Pool<Connection> pool = new Pool<Connection>(GetConnection, 0, 10, 80); //80 ms max age for fast testing

      Connection c1 = pool.Acquire();
      Connection c2 = pool.Acquire();
      Connection c3 = pool.Acquire();
      Connection c4 = pool.Acquire();

      pool.Release(c1);
      pool.Release(c2);
      pool.Release(c3);
      pool.Release(c4);

      Assert.IsTrue(pool.PoolSize == 4);
      Thread.Sleep(40);
      Assert.IsTrue(pool.PoolSize == 4);


      Connection c5 = pool.Acquire();
      Connection c6 = pool.Acquire();
      Connection c7 = pool.Acquire();
      pool.Release(c5);
      pool.Release(c6);
      pool.Release(c7);

      Assert.IsTrue(pool.PoolSize == 4);
      Thread.Sleep(80);
      Assert.IsTrue(pool.PoolSize == 3);
      Thread.Sleep(60);
      Assert.IsTrue(pool.PoolSize == 1);
    }

    [TestMethod()]
    public void PoolingTest2()
    {
      using (Pool<Connection> pool = new Pool<Connection>(GetConnection))
      {

        Connection c1 = pool.Acquire();
        Connection c2 = pool.Acquire();
        Connection c3 = pool.Acquire();
        Connection c4 = pool.Acquire();

        pool.Release(c1);
        pool.Release(c2);
        pool.Release(c3);
        pool.Release(c4);

        Assert.IsTrue(pool.PoolSize == 4);
      }
    }

    [TestMethod()]
    public void PoolingTest3()
    {
      try
      {
        Pool<Connection> pool = new Pool<Connection>(null);
        Assert.Fail();
      }
      catch (System.Exception ex)
      {
        Assert.IsTrue(ex.GetType() == typeof(ArgumentNullException));
      }
    }

    [TestMethod()]
    public void PoolingTest4()
    {
      Pool<Connection> pool = new Pool<Connection>(GetConnection, 2, 1, 10000);
      Connection c1 = pool.Acquire();
      Assert.IsTrue(pool.PoolSize == 2);

      Connection c2 = pool.Acquire();
      Connection c3 = pool.Acquire();
      Connection c4 = pool.Acquire();

      pool.Release(c1);
      pool.Release(c2);
      pool.Release(c3);
      pool.Release(c4);

      Assert.IsTrue(pool.PoolSize == 2);
    }

    private Connection GetConnection()
    {
      return new Connection() { Name = "Text Connection", Port = 58645, Server = "//DEV" };
    }
  }

  public class Connection : IDisposable
  {

    public string Name { get; set; }
    public string Server { get; set; }
    public int Port { get; set; }

    public void Connect()
    {

    }

    #region IDisposable Members

    public void Dispose()
    { }

    #endregion
  }
}